<!DOCTYPE html>
<html lang="en">
    <head>
        <!-- Required meta tags -->
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />

        <!-- Bootstrap CSS -->
        <link
            rel="stylesheet"
            href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha2/css/bootstrap.min.css"
            integrity="sha384-DhY6onE6f3zzKbjUPRc2hOzGAdEf4/Dz+WJwBvEYL/lkkIsI3ihufq9hk9K4lVoK"
            crossorigin="anonymous"
        />

        <title>Hello, world!</title>
    </head>
    <body>
        <div class="container">
            <div class="mt-5 form-file">
                <input type="file" class="form-file-input" id="myfileLoader" />
                <label class="form-file-label" for="myfileLoader">
                    <span class="form-file-text">请选择文件</span>
                    <span class="form-file-button">选择文件</span>
                </label>
            </div>

            <div class="progress mt-3">
                <div
                    class="progress-bar"
                    role="progressbar"
                    aria-valuenow="25"
                    aria-valuemin="0"
                    aria-valuemax="100"
                ></div>
            </div>

            <div class="mt-4">
                <span>传输速度：</span>
                <span id="speedSpan"></span>
            </div>

            <div class="mt-3">
                <button class="btn btn-primary">上传</button>
                <button class="btn btn-danger">取消上传</button>
            </div>
        </div>

        <script>
            // 获取 DOM 元素
            const progressBar = document.querySelector('.progress-bar');
            const fileLoaderInput = document.getElementById('myfileLoader');
            const speedSpan = document.getElementById('speedSpan');
            const uploadBtn = document.querySelector('.btn-primary');
            const cancleBtn = document.querySelector('.btn-danger');

            // 创建 ajax 对象
            const xhr = new XMLHttpRequest();

            // 上传按钮点击事件
            uploadBtn.addEventListener('click', () => {
                progressBar.style.width = {};
                progressBar.innerHTML = '';
                speedSpan.innerText = '';

                const file = fileLoaderInput.files[0];
                if (!file) {
                    alert('请先选择要上传的文件');
                    return;
                }

                // 创建一个表单对象
                const form = new FormData();
                form.append('myfile', file);

                xhr.open('POST', '/upload', true);

                xhr.responseType = 'json';

                // 开始上传时的记录点
                let startTime = Date.now();
                let alreadLoaded = 0;

                xhr.upload.onprogress = function (e) {
                    // 本次上传所用的时间
                    let usedTime = (Date.now() - startTime) / 1000;
                    // 本次上传了多少
                    let loadedTotal = e.loaded - alreadLoaded;
                    // 上传速度
                    let speed = loadedTotal / usedTime;
                    // 上传百分比
                    let percent = ((e.loaded / e.total) * 100).toFixed(0);

                    let unit = 'b/s';

                    if (speed / 1024 > 1) {
                        speed = speed / 1024;
                        unit = 'kb/s';
                    }

                    if (speed / 1024 > 1) {
                        speed = speed / 1024;
                        unit = 'mb/s';
                    }

                    // 重置记录点
                    startTime = Date.now();
                    alreadLoaded = e.loaded;

                    // 显示到页面上
                    progressBar.style.width = `${percent}%`;
                    progressBar.innerHTML = `${percent}%`;
                    speedSpan.innerText = speed.toFixed(0) + unit;
                };

                xhr.upload.onabort = function () {
                    console.log('取消上传');
                };

                xhr.upload.onloadend = function () {
                    console.log(
                        '上传完成，不管成功还是失败，还是取消了，都会调用这个函数'
                    );
                };

                xhr.upload.ontimeout = function () {
                    console.log('上传超时，服务器不理我');
                };

                xhr.upload.onerror = function () {
                    console.log('上传出错了');
                };

                xhr.onload = function () {
                    console.log(xhr.response);
                };

                // 开始发送
                xhr.send(form);
            });

            cancleBtn.addEventListener('click', function () {
                xhr.abort();
            });
        </script>
    </body>
</html>
